package com.woniuxy.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.dto.*;
import com.woniuxy.dto.UserRelatedDto.UsersSelRolesDto;
import com.woniuxy.dto.commonDto.BaseDto;
import com.woniuxy.entity.RoleTable;
import com.woniuxy.entity.UserRole;
import com.woniuxy.enums.CodeEnum;
import com.woniuxy.exception.PawnRoleException;
import com.woniuxy.mapper.RoleTableMapper;
import com.woniuxy.param.BaseParam;
import com.woniuxy.param.RolesPageAndByKeyParam;
import com.woniuxy.param.UserRelatedParam.SaveRoleParam;
import com.woniuxy.param.UserRelatedParam.UpdateRoleParam;
import com.woniuxy.service.RoleTableService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.service.UserRoleService;
import com.woniuxy.util.PageMysqlUtil;
import com.woniuxy.util.WoniuBeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zcx, ftl, gr, rhs
 * @since 2021-12-31
 */
@Service
public class RoleTableServiceImpl extends ServiceImpl<RoleTableMapper, RoleTable> implements RoleTableService {

    @Resource
    private UserRoleService urs;
    @Resource
    private StringRedisTemplate srt;

    private ObjectMapper om = new ObjectMapper();

    /**
     * 分页模糊查询
     *
     * @param rp
     * @return
     */
    @Override
    public BaseDto<RoleTable> listRoles(RolesPageAndByKeyParam rp) {
        QueryWrapper<RoleTable> query = new QueryWrapper<>();
        if (!StringUtils.isEmpty(rp.getKey())) {
            query.and(wrapper -> wrapper
                    .like("role_name", rp.getKey())
                    .or()
                    .like("role_nickname", rp.getKey())
            );
        }
        query.eq("role_status", 0);

        BaseDto<RoleTable> dto = PageMysqlUtil.pageQuery(RoleTable.class, this, query, new BaseParam(rp.getIndexPage(), rp.getPageSize()));


//        Page<RoleTable> rtp =
//                baseMapper.selectPage(new Page<>(rp.getIndexPage(), rp.getPageSize()), query);
//
//        PageRoleDto dto = new PageRoleDto();
//        //当前页数
//        dto.setIndexPage(rtp.getCurrent());
//        //最大数据
//
//        dto.setTotal(rtp.getTotal());
//
//        //判断是否有上一页
//        dto.setHasPrevious(rtp.hasPrevious());
//        //判断是否有下一页
//        dto.setHasNext(rtp.hasNext());
//
//        dto.setList(WoniuBeanUtils.copyList(rtp.getRecords(), RoleDto.class));
        return dto;

    }

    @Override
    public UsersSelRolesDto listRolesByUserId(Integer userId) {
        List<RoleTable> list = list(new QueryWrapper<RoleTable>().eq("role_status", 0));

        List<Integer> accountId = urs.list(new QueryWrapper<UserRole>().eq("user_id", userId))
                .stream().map(
                        ar -> ar.getRoleId()
                ).collect(Collectors.toList());


        UsersSelRolesDto dto = new UsersSelRolesDto();
        dto.setCheckedRoleIds(accountId);
        dto.setList(
                WoniuBeanUtils.copyList(list, RoleDto.class)

        );
        return dto;
    }

    @ExceptionHandler(Exception.class)
    @Override
    public boolean removeUserByIds(List<Integer> ids) {
        List<RoleTable> roles = listByIds(ids);
        if (ids.size() != roles.size())
            throw new PawnRoleException(CodeEnum.ROLE_DELETE_FAIL_1.getMessage(), CodeEnum.ROLE_DELETE_FAIL_1.getCode());


        for (RoleTable role : roles) {
            role.setRoleStatus(1);
        }

        return updateBatchById(roles);
    }


    @ExceptionHandler(Exception.class)
    @Override
    public boolean SaveRole(SaveRoleParam srp) {
        QueryWrapper<RoleTable> query = new QueryWrapper<>();
        //先判读是否有重名
        RoleTable role = getOne(new QueryWrapper<RoleTable>().eq("role_name", srp.getRoleName()));
        if (!StringUtils.isEmpty(role))
            throw new PawnRoleException(CodeEnum.ROLE_SAVE_FAIL_DUPLICATE_NAME.getMessage(), CodeEnum.ROLE_SAVE_FAIL_DUPLICATE_NAME.getCode());
        RoleTable roleTable = WoniuBeanUtils.copyObject(srp, RoleTable.class);
        roleTable.setRoleStatus(0);


        return save(roleTable);
    }

    @Override
    public RoleDto findRoleById(Integer roleId) throws JsonProcessingException {
        String roleJson = srt.opsForValue().get("role:info:id" + roleId);
        if (null == roleJson) {

            RoleTable role = getOne(new QueryWrapper<RoleTable>().eq("role_status", 0).eq("role_id", roleId));

            RoleDto dto = WoniuBeanUtils.copyObject(role, RoleDto.class);
            if (null != dto) {
                String json = null;
                json = om.writeValueAsString(dto);
                srt.opsForValue().set("role:info:id" + roleId, json, 1, TimeUnit.HOURS);
            }
            return WoniuBeanUtils.copyObject(role, RoleDto.class);

        } else {
            RoleDto dto = om.readValue(roleJson, RoleDto.class);
            return dto;

        }
    }

    @Override
    public boolean updateRole(UpdateRoleParam urp) {
        //修改，修改只能修改备注

        RoleTable roleTable = getOne(new QueryWrapper<RoleTable>().eq("role_id", urp.getRoleId()).eq("role_status", 0));
        if (StringUtils.isEmpty(roleTable))
            throw new PawnRoleException(CodeEnum.ROLE_NULL.getMessage(), CodeEnum.ROLE_NULL.getCode());


        //删除缓存
        String userJson = srt.opsForValue().get("role:info:id" + roleTable.getRoleId());
        if (null != userJson) {
            srt.delete("role:info:id" + roleTable.getRoleId());
        }
        roleTable.setRoleNickname(urp.getRoleNickname());


        return updateById(roleTable);
    }
}
